import { oops } from "db://oops-framework/core/Oops";
import { smc } from "../../../../common/ecs/SingletonModuleComp";
import { Role } from "../../../../role/Role";
import { BattleType } from "../../../scene/SceneEvent";
import { ISkillReport } from "../../model/report/ISkillReport";
import { Skill } from "../../Skill";
import { Effect } from "../../../scene/model/BattleEnum";
import { EffectDamage } from "../../model/report/EffectDamage";
import { RoleAttributeType } from "../../../../role/model/RoleEnum";
import { EffectBuff } from "../../model/report/EffectBuff";
import { EffectRecovery } from "../../../scene/model/EffectRecovery";
import { EffectImmune } from "../../model/report/EffectImmune";
import { EffectShield } from "../../model/report/EffectShield";

/** 
 * 技能数值计算模板
 */
export abstract class SkillCasting {
    /** 当前施放的技能 */
    skill: Skill = null!;
    /** 技能发起者 */
    caster: Role = null!;
    /** 玩家选中的技能释放目标或技能目标点 */
    target: Role = null!;
    /** 被攻击的玩家列表 */
    targets: Role[] = [];
    protected isr: ISkillReport = null!;

    getIsr(): ISkillReport {
        return this.isr;
    }
    /** 生成对指定目标释放技能战报 */
    casting_fire(target: Role): ISkillReport {
        this.isr = {
            sc: this,
            caster: this.caster,
            target: target,
            skill: this.skill,
            hits: []
        };
        return this.isr;
    }
    /** 生成对指定目标释放技能战报 */
    casting(target: Role, isCast: boolean = true) {
        if (!target || !target.RoleModel) {
            console.warn("target不存在")
            return
        }
        if (isCast) {
            this.isr = {
                sc: this,
                caster: this.caster,
                target: target,
                skill: this.skill,
                hits: []
            };
        }
        else {
            this.isr = {
                caster: this.caster,
                target: target,
                skill: this.skill,
                hits: []
            };
        }
        switch (target.RoleModel.battleType) {
            case BattleType.Scene:
                smc.scene.MapModelRole.reports.push(this.isr);
                break;
            case BattleType.Boss:
                // smc.boss.BossMapModelRole.reports.push(this.isr);
                console.warn("技能战报：boss todo");
                break;
            case BattleType.Tower:
                // smc.tower.TowerMapModelRole.reports.push(this.isr);
                console.warn("技能战报：塔 todo");

                break;
            default:
                break;
        }

        if (this.caster) {
            oops.log.trace(`【战斗】【${this.caster.RoleModel.pos}号位：${this.caster.RoleModel.table.name}】向【${target.RoleModel.pos}号位：${target.RoleModel.table.name}】释放【${this.skill.SkillModel.table.name}】技能`);
        }
        else {
            oops.log.trace(`【战斗】【玩家】向【${target.RoleModel.pos}号位：${target.RoleModel.table.name}】释放【${this.skill.SkillModel.table.name}】技能`);
        }
    }
    /**
  * 生成技能效果对目标的受击战报
  * @param isr       技能释放战报数据
  * @param target    受击目标角色（目标数据可能与技能选中的目标不一样，例如AOE技能）
  * @param effect    受击的技能效果数据
  * @returns         受击战报
  */
    hit(target: Role, effect: Effect) {
        var srh = { target: target, effect }
        this.isr.hits.push(srh);

        var skill = this.isr.skill;
        if (effect instanceof EffectBuff) {
            oops.log.trace(`【战斗】【${target.RoleModel.pos}号位：${target.RoleModel.table.name}】${effect.addto ? "添加" : "移除"}【BUFF】【${effect.buff.BuffModel.table.name}】，层数：【${effect.buff.BuffModel.overlying}】/【${effect.buff.BuffModel.table.overlying}】`);
        } else 
       if (effect instanceof EffectDamage) {
            var hp = target.getNumericValue(RoleAttributeType.hp_battle);
            var hp_max = target.hp;
            oops.log.trace(`【战斗】【${skill.SkillModel.table.name}】使【${target.RoleModel.pos}号位：${target.RoleModel.table.name}】受到【${effect.value}】点伤害，当前生命状态为【${hp}/${hp_max}】`);

            var shield = target.getNumericValue(RoleAttributeType.shield);
            var shieldDamage = effect.shieldDamage;
            if (shieldDamage) {
                oops.log.trace(`【战斗】【${skill.SkillModel.table.name}】使【${target.RoleModel.pos}号位：${target.RoleModel.table.name}】受到【${shieldDamage}】点护盾伤害，当前护盾值为【${shield}】`);
            }
        }
        else if (effect instanceof EffectRecovery) {
            var hp = target.getNumericValue(RoleAttributeType.hp_battle);
            var hp_max = target.hp;
            oops.log.trace(`【战斗】【${skill.SkillModel.table.name}】使【${target.RoleModel.pos}号位：${target.RoleModel.table.name}】恢复【${effect.value}】点生命【${hp}/${hp_max}】`);
        }
        else if (effect instanceof EffectImmune) {
            oops.log.trace(`【战斗】【${skill.SkillModel.table.name}】使【${target.RoleModel.pos}号位：${target.RoleModel.table.name}】免疫控制`);
        }
        else if (effect instanceof EffectShield) {
            oops.log.trace(`【战斗】【${skill.SkillModel.table.name}】使【${target.RoleModel.pos}号位：${target.RoleModel.table.name}】添加【${effect.shield}】点护盾值`);
        }
    }
    /** 学习技能事件 */
    onLearn() { }

    /** ----------攻击类事件---------- */
    /** 主动攻击前 */
    onCastBefore() { }
    /** 主动技能施放逻辑 */
    onCasting() { }
    /** 友军施放技能 */
    onFriendSkillCasting() { }
    /** 攻击后 */
    onCastAfter() { }
    /** 目标受到伤害前（计算无数值未赋值到目标角色时） */
    onHitBefore() { }
    /** 受到伤害后（计算无数值已赋值到目标角色时） */
    onHitAfter() { }
    /** 复活时 */
    onRevive() { }
    /** 自己死亡后 */
    onSelfDie() { }
    /** 队友死亡后 */
    onOtherDie() { }
    /** 敌方亡后 */
    onEnemyDie() { }
    /** 敌方BUFF添加完成时触发 */
    onEnemyBuffAdded(buffId: number, num: number) { }
    /** 敌方BUFF覆盖或叠加时触发 */
    onEnemyBuffCover(buffId: number, num: number) { }

    /** 行动前 */
    onActionBefore() { }
    /** 行动后 */
    onActionAfter() { }

    /** 战斗开始 */
    onBattleStart() { }
    /** 战斗结束 */
    onBattleEnd() { }
    /** 回合开始 */
    onRoundStart() { }
    /** 回合结束 */
    onRoundEnd() { }
    /** 任何人受击前 */
    onAllHitBefore() { }
    /** 任何人受击后 */
    onAllHitAfter() { }
    /** 战场中有角色死亡事件 */
    onDieBattle() { }
    /** 友方护盾消失 */
    onFriendShieldOver() { }
    /** 格挡时 */
    onBlock() { }
}